// zp - zoom power, the more the zp the faster zoom-in zoom-out happens
var zp = 1.5;
var svgns = "http://www.w3.org/2000/svg";
function View(svg) {
	this.svg = svg;
	// Create an SVGPoint for future math
	this.svgpt = svg.createSVGPoint();
	this.listeners = [];
	this.reset = function() {
		// d - density, number of pixels for each x/y value increment
		this.d = 50;
	};
	// Get point in global SVG space
	this.getCursorPoint = function(evt) {
		this.svgpt.x = evt.clientX;
		this.svgpt.y = evt.clientY;
		return this.svgpt.matrixTransform(this.svg.getScreenCTM().inverse());
	};
	this.toUnit = function(p) {
		return p / this.d;
	};
	this.myEventListener = function(e) {
		var loc = view.getCursorPoint(e);
		loc.x = view.toUnit(loc.x);
		loc.y = view.toUnit(loc.y);
		for(var i = 0; i < view.listeners.length; i++)
			view.listeners[i](loc);
	};
	this.addEventListener = function(eventType, handler) {
		this.listeners[this.listeners.length] = handler;
		svg.addEventListener(eventType, this.myEventListener);
	};
	this.removeEventListener = function(handler) {
		for(var i = 0; i < this.listeners.length; i++) {
			if(this.listeners[i] == handler)
				this.listeners.slice(i, i--);
		}
	};
	this.clear = function() {
		while (this.svg.lastChild)
			this.svg.removeChild(this.svg.lastChild);
	};
	this.square = function(x, y, s, c, psw) {
		this.rectanglep(this.toPixel(x), this.toPixel(y), this.toPixel(s), this.toPixel(s), c, psw);
	};
	this.rectanglep = function(px, py, pw, ph, c, psw) {
		this.hlinep(px + psw, py + ph / 2, pw - 2 * psw, c, ph - 2 * psw);
	};
	this.zoomin = function() {
		this.d *= zp;
	};
	this.zoomout = function() {
		this.d /= zp;
	};
	this.hline = function(x, y, l, c, pt) {
		this.hlinep(this.toPixel(x), this.toPixel(y), this.toPixel(l), c, pt);
	};
	this.hlinep = function(px, py, pl, c, pt) {
		for(var pyi = py - pt / 2; pyi < py + pt / 2; pyi++)
			this.linep(px, pyi, px + pl, pyi, c);
	};
	this.vline = function(x, y, l, c, pt) {
		this.vlinep(this.toPixel(x), this.toPixel(y), this.toPixel(l), c, pt);
	};
	this.vlinep = function(px, py, pl, c, pt) {
		for(var pxi = px - pt / 2; pxi < px + pt / 2; pxi++)
			this.linep(pxi, py, pxi, py + pl, c);
	};
	this.line = function(x1, y1, x2, y2, c, t) {
		this.linep(this.toPixel(x1), this.toPixel(y1), this.toPixel(x2), this.toPixel(y2), c);
	};
	this.linep = function(px1, py1, px2, py2, c) {
		var shape = document.createElementNS(svgns, "line");
		shape.setAttributeNS(null, "x1", px1);
		shape.setAttributeNS(null, "y1", py1);
		shape.setAttributeNS(null, "x2", px2);
		shape.setAttributeNS(null, "y2", py2);
		shape.setAttributeNS(null, "stroke", c);
		shape.setAttributeNS(null, "stroke-width", "1");
		this.svg.appendChild(shape);
	};
	this.toPixel = function(u) {
		return u * this.d;
	};
	this.circle = function(x, y, pr) {
		this.circlep(this.toPixel(x), this.toPixel(y), pr);
	};
	this.circlep = function(px, py, pr) {
		var shape = document.createElementNS(svgns, "circle");
		shape.setAttributeNS(null, "cx", px);
		shape.setAttributeNS(null, "cy", py);
		shape.setAttributeNS(null, "r",  pr);
		shape.setAttributeNS(null, "fill", "black");
		shape.setAttributeNS(null, "stroke", "black");
		shape.setAttributeNS(null, "stroke-width", "1");
		this.svg.appendChild(shape);
	};
	this.setWidth = function(w) {
		this.svg.setAttribute('width', this.toPixel(w));
	};
	this.setHeight = function(h) {
		this.svg.setAttribute('height', this.toPixel(h));
	};
	this.reset();
}